﻿#region Using References

using System;
using System.Collections.Generic;
using System.Data.Entity;
using Beaker.OpenCube.CubeManager.Model.Configurations;
using Beaker.OpenCube.CubeManager.Model.Entities;
using Beaker.OpenCube.CubeManager.Model.Framework;
using Beaker.OpenCube.CubeManager.Model.Interfaces;
using Beaker.OpenCube.CubeManager.Model.Repositories;

#endregion

namespace Beaker.OpenCube.CubeManager.Model
{
	public sealed class CubeManagerUnitOfWork
		: IUnitOfWork
	{
		private readonly Dictionary<Type, IRepository> _repositories;
		private readonly CubeManagerDbContext _context;

		public CubeManagerUnitOfWork()
		{
			_context = new CubeManagerDbContext();
			_repositories = new Dictionary<Type, IRepository>();
		}

		/// <summary>
		/// Gets the repository for the given type.
		/// </summary>
		/// <typeparam name="TEntity">The type of the entities in the repository.</typeparam>
		/// <returns>The requested repository.</returns>
		private IRepository<TEntity> GetRepository<TEntity>()
			where TEntity : Entity
		{
			// try to find an existing repository
			IRepository repository;
			if( !_repositories.TryGetValue( typeof( TEntity ), out repository ) )
			{
				// not found, create a new one.
				repository = RepositoryFactory.Create<TEntity>( this );
				_repositories.Add( typeof( TEntity ), repository );
			}

			return (IRepository<TEntity>)repository;
		}

		public ServerRepository Servers
		{
			get { return (ServerRepository)GetRepository<Server>(); }
		}

		public MachineRepository Machines
		{
			get { return (MachineRepository)GetRepository<Machine>(); }
		}

		void IUnitOfWork.SaveChanges()
		{
			_context.SaveChanges();
		}

		#region Implementation of IDisposable

		/// <summary>
		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
		/// </summary>
		/// <filterpriority>2</filterpriority>
		public void Dispose()
		{
			throw new NotImplementedException();
		}

		#endregion
	}
}
